
from os.path import exists
from utils.tencent.cos import check_file
from web import models
from django import forms
from django.core.exceptions import ValidationError
from utils.BootStrapForm import BootStrapForm

class FolderModelForm(BootStrapForm,forms.ModelForm):
    class Meta:
        model = models.Filerepository
        fields = ['name']
    def __init__(self,request,parent_object,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.request = request
        self.parent_object = parent_object

    # 通过钩子函数来防止同一个目录下面的文件夹重名
    def clean_name(self):
        # 获取当前post推送过来的文件夹名称
        name = self.cleaned_data['name']
        # 跟数据库中的文件夹名称进行比对
        ##　根据传入的父目录对象：parent_object，来判断在同一个目录下面是否有重名的文件夹。如果父目录不存在时，就在数据库根目录下面查找是否有重名文件夹
        queryset = models.Filerepository.objects.filter(file_type=2,name=name,project=self.request.tracer.project)
        if self.parent_object:
            exists = queryset.filter(parent=self.parent_object).exists()
        else:
            exists = queryset.filter(parent__isnull=True).exists()
        if exists: # 如果在根目录或者是某个目录下有重名的就会抛出这个异常提示
            raise ValidationError("文件夹已存在")
        return name


class FileModelForm(BootStrapForm,forms.ModelForm):
    """ 校验上传的文件 """
    etag = forms.CharField(label='ETag')  # 新增一个字段用来校验传送的文件
    class Meta:
        model = models.Filerepository
        exclude = ['project','file_type','update_user','update_datetime']

    def __init__(self,request,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.request = request

    def clean_file_path(self):
        return "https://{}".format(self.cleaned_data['file_path'])

    def clean(self):
        etag = self.cleaned_data['etag']
        key = self.cleaned_data['key']
        size = self.cleaned_data['file_size']
        if not key or not etag:
            return self.cleaned_data
        # 调用COS校验文件的函数，验证数据是否合法,COS后台如果检测不到数据的话就抛出一个异常信息
        from qcloud_cos.cos_exception import CosServiceError
        try:
            result = check_file(self.request.tracer.project.bucket,self.request.tracer.project.region,key)
        except CosServiceError as e:
            self.add_error(key,'文件不存在')
            return self.cleaned_data
        cos_etag = result.get('ETag')
        # 让前端的数据跟cos中获取的数据进行比较
        if etag != cos_etag:
            self.add_error('etag', 'ETag错误')
        # cos中获取的文件大小，跟前端获取的文件大小作比较
        cos_length = result.get('Content-Length')
        if int(cos_length) != size:
            self.add_error('file_size', '文件大小错误')

        return self.cleaned_data





